﻿using log4net;
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;

namespace Klinkby.MicroBus
{
    /// <summary>
    /// Filters messages on topic by wildcard
    /// </summary>
    [Serializable]
    internal class Filter : AsyncFilter
    {
        readonly static ILog _log = LogManager.GetLogger(typeof(Filter));
        readonly Regex _filter;
        
        Filter(Regex filter, IAsyncFilter[] children)
            : base(children)
        {
            _filter = filter;
        }

        public override void Process(IMessage message)
        {
            _log.Debug("Matching " + message.Topic);
            if (_filter.IsMatch(message.Topic))
            {
                _log.Info("Pass " + message.Topic);
                base.Process(message);
            }
        }

        public static IAsyncFilter FromXml(XElement e, IAsyncFilter[] children)
        {
            _log.Debug("Deserializing");
            Safe.NonNull(e, "e");
            Safe.Validate(e, () => "Filter" == e.Name.LocalName, "Not a Filter element");
            string regex = WildcardToRegex(e.AttributeValue("topic"));
            _log.Debug("Regex: " + regex);
            return new Filter(
                new Regex(regex, RegexOptions.Compiled | RegexOptions.CultureInvariant),
                children);
        }

        static string WildcardToRegex(string pattern)
        {
            return Regex.Escape(pattern).
                Replace("\\*", ".*").
                Replace("\\?", ".");
        }
    }
}
